<template>
	<div>jstest3</div>
	<input v-model="msg" ref="myRef" /> <button @click="copyToClipboard()"> 复制内容</button>
	<div style="height: 888px;">jstest3</div>
	<button @click="scrollToTop">返回顶部</button>

</template>

<script>
	import {
		ref,
		reactive,
		onMounted
	} from 'vue'
	export default {
		//Vue3获取Dom元素
		//1.dom上写上ref 2setup函数内部写上ref 3retrun 出来（重点）
		setup() {
			const myRef = ref(null);

			onMounted(() => {
				console.log(myRef, myRef.value);
				var details = myRef.value
				console.dir(details) //console.dir()可以显示一个对象所有的属性和方法
			});
			return {
				myRef,
			}
		},
		data() {
			return {
				msg: '123'
			}
		},
		created() {
			const bottomVisible = () =>
				// 窗体高度+滑动Y >= 窗体高度
				// window.scrollY = document.documentElement.scrollTop
				document.documentElement.clientHeight + window.scrollY >=
				(document.documentElement.scrollHeight ||
					document.documentElement.clientHeight);
			window.onscroll = () => {
				var bottomFlag = bottomVisible(); // true
				// console.log(' ', bottomFlag, window.scrollY)
				if (bottomFlag) {
					console.log('页面底部是否可见', bottomFlag)
				}
			}

			window.oncontextmenu = () => {
				console.log("点击了右键");
			};

			const isBrowserTabIsFocus = () => document.hidden;
			console.log("检查标签浏览器是否在视图中", document.hidden, isBrowserTabIsFocus);


		},
		mounted() {
			this.birthDay();
			this.objectSample();
			this.arrangeTest();
			this.needParams();
			this.arrayToObject();
			this.sortTest();
			this.modalHelperTest();
			this.finallyTest();
			this.keyValueMap();
			this.testTimer();
			this.indexOfTest();
			this.isNumberTest();
			this.maxArrayTest();
		},
		methods: {
			birthDay() {
				console.log('生成指定范围的随机数', '='.repeat(10))
				var getRandoms = (min, max) => {
					return Math.round(Math.random() * (max - min) + min)
				}
				console.log("[10, 100]=", getRandoms(10, 100));

				//随机获取数组中的一项元素
				var arrayCities = ["北京", "上海", "广州", "深圳", "天津", "重庆"];
				var getRandomItem = (array) => array[Math.round(Math.random() * (array.length - 1))]
				console.log("随机城市：", getRandomItem(arrayCities));
			},

			objectSample() {
				console.log('数字加密解密', '='.repeat(10))

				function Encrypt(secretNumber = 202108) {
					const _secretNumber = secretNumber;
					const encrypted = (encryptNumber) => encryptNumber ^ secretNumber;
					const decrypted = (encryptedContent) => encryptedContent ^ secretNumber;
					return {
						encrypted,
						decrypted
					}
				}

				const encryptHelper = new Encrypt(202108);
				const encryptNumber = 20210901;

				// 加密
				const encrypted = encryptHelper.encrypted(encryptNumber);
				console.log(encrypted); // 20410793
				// 解密
				const decrypted = encryptHelper.decrypted(encrypted);
				console.log(decrypted); // 20210901

			},

			//此代码片段用于计算执行函数所需的时间
			timeTaken(callback, tag = "执行时间：") {
				console.time(tag);
				const result = callback();
				console.timeEnd(tag);
				return result;
			},

			arrangeTest() {
				console.log('冒泡排序+选择排序', '='.repeat(10))

				// 冒泡排序:大的元素往后面冒泡
				function bubbleSort(arr) {
					var len = arr.length;
					for (var i = 0; i < len; i++) {
						// console.log(j,arr[j],j+1,arr[j + 1])
						for (var j = 0; j < len - 1 - i; j++) {
							if (arr[j] > arr[j + 1]) { //相邻元素两两对比
								var temp = arr[j + 1]; //元素交换
								arr[j + 1] = arr[j];
								arr[j] = temp;
							}
						}
						// console.log('arr',arr)
					}
					return arr;
				}

				const timeTaken = (callback, tag = "执行时间：") => {
					console.time(tag);
					const result = callback();
					console.timeEnd(tag);
					return result;
				};

				var arr = [5, 4, 2, 3, 9, 1, 8, 6, 5]
				// console.time("bubbleSort==")
				// arr = bubbleSort(arr)
				// console.timeEnd("bubbleSort==", arr)
				timeTaken(() => {
					bubbleSort(arr, 'bubbleSort==')
				}, '===bubbleSort执行时间===')

				// 选择排序
				function selectionSort(arr) {
					var len = arr.length
					var minIndex, temp;
					for (var i = 0; i < len - 1; i++) {
						minIndex = i;
						// 1每次比较把当前最小值的索引保存，
						// 2继续把当前最小值比较后面的元素
						// 3比较完一轮，得出最小值的索引
						for (var j = i + 1; j < len; j++) {
							if (arr[j] < arr[minIndex]) { //寻找最小的数
								minIndex = j //将最小数的索引保存
							}
						}
						//比较完第一轮：minIndex=5，和i交换位置
						if (minIndex != i) {
							temp = arr[i]
							arr[i] = arr[minIndex]
							arr[minIndex] = temp
						}
						//此时最小值排到了最前面[1, 4, 2, 3, 9, 5, 8, 6, 5]
					}
					return arr
				}
				var arr = [5, 4, 2, 3, 9, 1, 8, 6, 5]
				selectionSort(arr)
				this.timeTaken(() => {
					selectionSort(arr)
				}, '===selectionSort===')
			},

			needParams() {
				console.log('设置必选参数', '='.repeat(10))
				var madatory = (name) => {
					throw new Error(`调用错误，必须传递参数：${name}`)
				}
				const printTitle = (title = madatory("标题")) => {
					console.log(`打印文章标题：${title}`);
				}
				printTitle("JavaScript"); // 打印文章标题：JavaScript
				// printTitle(); // Error: 调用错误，必须传递参数：标题
			},

			arrayToObject() {
				console.log('数组项的对象解构', '='.repeat(10))
				const csvAddressDetail = "广东省,深圳市,南山区,科技园北区科技园大厦";
				var arrayAddress = csvAddressDetail.split(',')
				var {
					0: province,
					1: city,
					2: district,
					3: address
				} = arrayAddress;
				console.log(province, city, district, address);
			},

			sortTest() {
				console.log('sort内部元素的比较排序理解', '='.repeat(10))
				var arr = [10, 3, 2, 4]
				console.log('arr', '[10,3,2,4]')
				arr.sort((a, b) => {
					console.log(a, b)
					//3 10  3-10为负数，3排10前面
					//2 3  2-3为负数，2排3前面，***10比3大，3比2大，此时2不需要再和10比较
					//4 2  4-3为正数，2排4前面
					//4 3  4-3为正数，3排4前面
					//4 10  4-10为负数，4排10前面
					return a - b
				})
				console.log('arr', arr) //[2, 3, 4, 10]
			},

			modalHelperTest() {
				console.log('支持方法的链式调用', '='.repeat(10))

				function CusModal() {
					const This = this;
					this.options = {
						theme: "default",
						title: "modal",
						visible: false,
					};
					const setOptions = function(key, value) {
						This.options[key] = value;
					};
					this.setTheme = function(theme) {
						setOptions("theme", theme);
						return this;
					};
					this.setTitle = function(title) {
						setOptions("title", title);
						return this;
					};
					this.show = function() {
						setOptions("visible", true);
					};
					this.close = function() {
						setOptions("visible", false);
					};
					this.getOptions = function() {
						return this.options;
					};
				}
				const modalHelper = new CusModal();
				// 设置弹窗主题、设置标题、显示
				modalHelper.setTheme("dark").setTitle("发布文章窗口").show();
				console.log(modalHelper.getOptions());
			},

			finallyTest() {
				console.log('不管是否有异常都会执行finally', '='.repeat(10))
				const testError = (val) => {
					try {
						const number = 100 / val;
						return number;
					} catch (error) {
						return error;
					} finally {
						console.log("finally");
					}
				};
				console.log(testError(10)); // finally  10
				console.log(testError(0)); // finally Infinity
			},


			finallyTest() {
				console.log('查找重复项或者重复次数最多的元素', '='.repeat(10))

				function maxRepeated(array) {
					//第二个a元素出现的次数和第一个b元素出现的次数比较排序
					return array.sort((a, b) =>
							array.filter((v) => v === a).length -
							array.filter((v) => v === b).length
						)
						.pop()
				}
				const arrString = ["china", "beijing", "shenzhen", "shanghai", "shenzhen"];
				const arrNumbers = [10, 20, 30, 10, 20, 10];
				console.log(maxRepeated(arrString)); // shenzhen
				console.log(maxRepeated(arrNumbers)); // 10
			},

			//此代码片段使用 Object.keys 方法和 map 方法来映射 Object 的键，创建一个键值对数组。
			keyValueMap() {
				console.log('Object.keys 方法和 map 方法创建一个键值对数组', '='.repeat(10))
				const keyValuePairs = (object) => Object.keys(object).map((key) => [key, object[key]]);
				var obj = {
					title: "DevPoint",
					city: "Shenzhen"
				}
				var objArr = keyValuePairs(obj)
				console.log('objArr', objArr) //// [ [ 'title', 'DevPoint' ], [ 'city', 'Shenzhen' ] ]
			},

			//此代码片段使用 Object.keys 方法和 map 方法来映射 Object 的键，创建一个键值对数组。
			scrollToTop() {
				var timer = null;
				cancelAnimationFrame(timer);
				timer = requestAnimationFrame(function fn() {
					var oTop = document.body.scrollTop || document.documentElement.scrollTop;
					if (oTop > 0) {
						scrollTo(0, oTop - 20);
						timer = requestAnimationFrame(fn); //递归调用
					} else {
						cancelAnimationFrame(timer);
					}
				});
			},

			// 将输入复制到剪贴板
			copyToClipboard() {
				var value = this.myRef.value
				console.log('value', value)
				try {
					navigator.clipboard.writeText(value);
				} catch (e) {
					const input = document.createElement('input');
					document.body.appendChild(input);
					input.setAttribute('style',
						'position:fixed;top:-9999px;left:-9999px;') // 它是可见的，但它又是不可见的
					input.value = value;
					input.focus();
					input.select();
					const result = document.execCommand('copy');
					input.style.display = 'none';
					if (result === 'unsuccessful') {
						console.log('复制失败，请手动复制！');
						return;
					}
					console.log('复制成功');
				}
			},

			testTimer() {
				class Timer {
					constructor(fn, delay) {
						this._triggerTimer = null;
						this._delay = delay;
						this._fn = fn;
					}

					stop() {
						if (this._triggerTimer) {
							clearTimeout(this._triggerTimer);
							this._triggerTimer = null;
						}
					}

					begin() {
						this.stop();
						this._triggerTimer = setTimeout(() => {
							this._fn();
						}, this._delay);
					}
				}
				let timerCount = 0;
				const timerHelper = new Timer(() => {
					timerCount++;
					if (timerCount < 5) {
						console.log(timerCount);
						timerHelper.begin();
					} else {
						timerHelper.stop();
					}
				}, 500);
				timerHelper.begin();
			},

			// 此代码片段用于查找数组中包含元素的所有索引值，返回索引值组成的数组，没有则返回空数组
			indexOfTest() {
				console.log('此代码片段用于查找数组中包含元素的所有索引值，返回索引值组成的数组，没有则返回空数组', '='.repeat(10))
				const indexOfAll = (array, val) =>
					array.reduce(
						(acc, current, index) => (current === val ? [...acc, index] : acc),
						[]
					);
				const testArray = ["devpoint", "devtest", "javascript", "devtest"];
				console.log('indexOfTest=', indexOfAll(testArray, "devtest")); // [ 1, 3 ]

			},

			//此代码片段用于检查数据是否为数字
			isNumberTest() {
				console.log('此代码片段用于检查数据是否为数字', '='.repeat(10))
				const isNumber = (num) => {
					return !isNaN(parseFloat(num)) && isFinite(num);
				};
				const testObj = {
					title: "devpoint",
				};
				console.log(isNumber(testObj.age)); // false
				console.log(isNumber("1a")); // false
				console.log(isNumber(1)); // true
			},

			//此代码片段用于检查字符串是否为有效的 JSON 字符串
			isValidJSONTest() {
				console.log('此代码片段用于检查字符串是否为有效的 JSON 字符串', '='.repeat(10))
				const isValidJSON = (str) => {
					try {
						JSON.parse(str);
						return true;
					} catch (e) {
						return false;
					}
				}
				const testObj = {
					title: "devpoint",
				};
				console.log(isValidJSON('{"name":"devpoint","age":30}')); // true
				console.log(isValidJSON(null)); // true
			},

			//此代码片段返回数组中的 n 个最大元素
			maxArrayTest() {
				console.log('此代码片段返回数组中的 n 个最大元素', '='.repeat(10))
				const maxArray = (array, n = 1) => [...array].sort((a, b) => b - a).slice(0, n)
				const testArray = [10, 2, 3, 30, 9];
				console.log(maxArray(testArray)); // [ 30 ]
				console.log(maxArray(testArray, 2)); // [ 30, 10 ]
				console.log(maxArray(testArray, 3)); // [ 30, 10, 9 ]
			},


		},
	}
</script>

<style>
</style>
